#include "../../include/tasktype.h"
#include "../../include/task.h"
#include "../../include/myPrintk.h"

myTCB *Q_gettop(Q_LIST *tskhandler)
{
	if (tskhandler->start == 0)
		return idleTask;
	else
		return tskhandler->start;
}

void Q_enqueue(Q_LIST *tskhandler, myTCB *tsk)
{
	if (tskhandler->start == 0)
	{
		tskhandler->start = tskhandler->end = tsk;
		tskhandler->end->next = 0;
		return;
	}
	tskhandler->end->next = tsk;
	tskhandler->end = tsk;
	tsk->next = 0;
	return;
}

myTCB *Q_dequeue(Q_LIST *tskhandler)
{
	myTCB *TCB = tskhandler->start;
	if (tskhandler->start == 0)
		return TCB;
	if (tskhandler->start == tskhandler->end)
	{
		tskhandler->start = tskhandler->end = 0;
		return TCB;
	}
	tskhandler->start = tskhandler->start->next;
	return TCB;
}

myTCB *Q_destroy(Q_LIST *tskhandler, int tid)
{
	myTCB *p = tskhandler->start;
	if (p == 0)
		return 0;
	if (p->tid == tid)
	{
		if (p == tskhandler->end)
			tskhandler->start = tskhandler->end = 0;
		else
		{
			tskhandler->start = p->next;
			p->next = 0;
		}
		return p;
	}
	while (p->next != 0)
	{
		if (p->next->tid == tid)
		{
			myTCB *q = p->next;
			p->next = q->next;
			q->next = 0;
			if (q == tskhandler->end)
				tskhandler->end = p;
			return q;
		}
		p = p->next;
	}
}

void Q_print(Q_LIST *handler)
{
	myTCB *p = handler->start;
	int i = 0;
	while (p != 0)
	{
		myPrintk(0x6, "%d ", p->tid);
		p = p->next;
		i++;
		if (i == 8)
			break;
	}
	myPrintk(0x06, "\n");
	return;
}

static int Q_sort_priority(myTCB *p1, myTCB *p2)
{
	if (p1->priority > p2->priority)
		return -1;
	else if (p1->priority == p2->priority)
		return 0;
	else if (p1->priority < p2->priority)
		return 1;
}

static int Q_sort_fcfs(myTCB *p1, myTCB *p2)
{
	if (p1->arrTime > p2->arrTime)
		return -1;
	else if (p1->priority == p2->arrTime)
		return 0;
	else if (p1->arrTime < p2->arrTime)
		return 1;
}

static int Q_sort_sjf(myTCB *p1, myTCB *p2)
{
	if (p1->exeTime > p2->exeTime)
		return -1;
	else if (p1->exeTime == p2->exeTime)
		return 0;
	else if (p1->exeTime < p2->exeTime)
		return 1;
}

int (*sort_func)(myTCB *, myTCB *);

void Q_sort(Q_LIST *handler, sch_policy sch)
{
	switch (sch)
	{
	case FCFS:
		sort_func = Q_sort_fcfs;
		break;
	case PRIO:
		sort_func = Q_sort_priority;
		break;
	case SJF:
		sort_func = Q_sort_sjf;
		break;
	case RR:
		return;
	}
	myTCB temp;
	myTCB *p1 = handler->start, *p2 = p1;
	while (p1->next != 0)
	{
		p2 = p1->next;
		while (p2 != 0)
		{
			if (sort_func(p1, p2) < 0)
			{
				temp = *p2;
				myTCB *tmp = p2->next;
				*p2 = *p1;
				p2->next = tmp;
				tmp = p1->next;
				*p1 = temp;
				p1->next = tmp;
			}
			p2 = p2->next;
		}
		p1 = p1->next;
	}
	return;
}
